/*
 * @Date: 2022-03-11 11:01:06
 * @Version: 1.0.0
 * @Author: minichen
 * @Description: popup
 * @FilePath: \bmap-libs\src\plugin\popup.js
 * @LastEditTime: 2022-03-25 09:10:16
 * @LastEditors: minichen
 */
import customOverlay from './customOverlay';

export default function () {
  const BMapGLLib = (window.BMapGLLib = window.BMapGLLib || {});

  let BMap = window.BMap || window.BMapGL;

  if (!BMap) {
    console.error('bamp-libs: BMap or BMapGL is not found!');
    return;
  }

  const CustomOverlay = customOverlay(BMap);

  function Popup(content, options) {
    if (!content) {
      console.error('bamp-libs: Params error!');
      return null;
    }

    const _options = {
      zIndex: 1,
      offset: new BMap.Size(0, 0),
      className: '',
      visible: true,
      pane: 'labelPane',
    };

    // 参数
    this._content = content;
    this._options = { ..._options, ...options };

    // 状态
    this._initialized = false; // 是否初始化
    this._removed = false; // 是否移除
    this._needUpdate = false; // 是否需要更新

    // 属性
    this._map = null; // 地图实例
    this._point = null; // 坐标点
    this._container = null; // dom节点
    this._size = null; // dom尺寸
    this._anchor = new BMap.Size(0, 0); // 锚点，用于挂载到marker上定位
    this._follow = false; // 是否进入伴随状态
    this._followVisible = false; // 伴随显示状态

    // 增强子类
    CustomOverlay.call(this);
  }

  Popup.prototype = Object.create(CustomOverlay.prototype);
  Popup.prototype.constructor = Popup;

  Popup.prototype.initialize = function (map) {
    // 参数有误
    if (this._initialized === undefined) return;

    // 创建popup
    const popup = document.createElement('div');
    popup.className = ('bmap-popup ' + this._options.className).trim();
    popup.style.position = 'absolute';

    this._map = map;
    this._container = popup;

    // 设置层级
    this.setZIndex(this._options.zIndex);
    // 将自定义popup内容添加到popup节点中
    this._appendContainerContent();
    // 添加事件（添加到地图之前绑定的事件）
    this._patchEventHandle(this._bindEvent);
    // 监听clearoverlays事件
    this._addClearoverlaysEvent();

    this._initialized = true;

    if (this._point) {
      this._initDom();
    }

    return popup;
  };

  Popup.prototype.draw = function () {
    if (!this._initialized || !this._point) return;

    // 移除后重新添加节点
    if (this._removed) {
      // 重新添加节点
      this._addDom();
      // 重新绑定事件
      this._patchEventHandle(this._bindEvent);
      // 重新监听clearoverlays事件
      this._addClearoverlaysEvent();

      this._removed = false;
    }

    // 检测更新，更新尺寸
    if (this._needUpdate && this.isVisible()) {
      this._getContainerSize();
      this._needUpdate = false;
    }

    // 调整位置
    const pixel = this._map.pointToOverlayPixel(this._point);
    this._container.style.left =
      pixel.x - this._size.width / 2 + this._anchor.width + this._options.offset.width + 'px';
    this._container.style.top = pixel.y - this._size.height + this._anchor.height + this._options.offset.height + 'px';
  };

  Popup.prototype.remove = function () {
    if (!this._initialized || !this._point || this._removed) return;

    // 伴随状态重置
    this._follow = false;
    // 移除clearoverlays事件
    this._removeClearoverlaysEvent();
    // 移除节点事件
    this._patchEventHandle(this._unbindEvent);
    // 移除节点
    this._removeDom();

    this._removed = true;
  };

  /**
   * @description: 更新
   * @param {*}
   * @return {*}
   */
  Popup.prototype.update = function () {
    this._needUpdate = true;
    this._draw();
  };

  /**
   * @description: 初始化节点
   * @param {*}
   * @return {*}
   */
  Popup.prototype._initDom = function () {
    this._addDom();
    this._getContainerSize();

    Promise.resolve().then(() => {
      if (!this._options.visible) {
        this.hide();
      }
    });
  };

  /**
   * @description: 重写show方法，因为可能需要更新
   * @param {*}
   * @return {*}
   */
  Popup.prototype.show = function () {
    if (this._follow) {
      this._followVisible = true;
      return;
    }

    BMap.Overlay.prototype.show.call(this);

    if (this._needUpdate) {
      this._draw();
    }
  };

  /**
   * @description: 重写hide方法
   * @param {*}
   * @return {*}
   */
  Popup.prototype.hide = function () {
    if (this._follow) {
      this._followVisible = false;
      return;
    }

    BMap.Overlay.prototype.hide.call(this);
  };

  /**
   * @description: 伴随隐藏（绑定的marker隐藏了，该popup也要隐藏）
   * @param {*}
   * @return {*}
   */
  Popup.prototype._followHide = function () {
    if (this._follow) return;

    this._follow = true;
    this._followVisible = this.isVisible();
    BMap.Overlay.prototype.hide.call(this);
  };

  /**
   * @description: 伴随显示（绑定的marker显示了，该popup应该恢复到之前的状态）
   * @param {*}
   * @return {*}
   */
  Popup.prototype._followShow = function () {
    if (!this._follow) return;

    this._follow = false;
    if (this._followVisible) {
      this.show();
    }
  };

  /**
   * @description: 添加坐标
   * @param {*} point
   * @return {*}
   */
  Popup.prototype.setPoint = function (point) {
    if (!(point instanceof BMap.Point)) return;

    // 已初始化但为未设置过坐标
    if (this._initialized && !this._point) {
      this._initDom();
    }

    // 更新位置
    this._point = point;
    this._draw();
  };

  /**
   * @description: 设置锚点
   * @param {*} anchor
   * @return {*}
   */
  Popup.prototype._setAnchor = function (anchor) {
    if (!(anchor instanceof BMap.Size)) return;

    this._anchor = anchor;
    this._draw();
  };

  BMapGLLib.Popup = Popup;
}
